#include <stdio.h>
#include <stdlib.h>
#define JD 0.5 // 精度要求
#define NN 1000 //gene数量
double pow(double a, int b)
{
   double r;
   if (a == 0)
      return 0;
   if (b == 0)
      return 1;
   r = 1;
   while (b > 0)
   {
      r *= a;
      b--;
   }
   return r;
}
void die(char *msg)
{
   printf("%s\n", msg);
   exit(1);
}
int calc(int N, int NUM, double *X)
//N最高次数+1NUM组验证数据
{
   int n, num;
   n = 0, num = 0;
   FILE *fp;
   unsigned int seed;
   int seed1;
   double *tmp, temp;
   double jd[NN]; //记录精度
   double avr_jd, last_jd;
   int i, j, t, m;
   double gene[NN][N];
   int ttt;
   fp = fopen("/dev/random", "rb");
   if (!fp)
      die("Error 6: 无法打开 /dev/random");
   printf("waiting for a randomize seed...");
   while (fread(&seed, sizeof(seed), 1, fp) != 1)
      ;
   printf("OK!\n");
   seed1 += seed;
   srand(seed1);
   fclose(fp);
   for (i = 0; i < NN; i++)
      for (j = 0; j < N; j++)
         gene[i][j] = (double)(rand() % 100) - 50;	//-50~50
   avr_jd = 999;
   ttt = 0;
   while (avr_jd *10 > JD)
   {
      ttt++;
      last_jd = avr_jd;
      avr_jd = 0;
      for (i = 0; i < NN; i++)
      {
         jd[i] = 0;
         tmp = X;
         for (t = 0; t < NUM; t++)
         {
            m = 0;
            temp = 0;
            while (m < N)
            {
               temp += gene[i][m] *pow(*tmp, m);
               m++;
            }
            jd[i] += (temp - *(tmp + 1) > 0) ? (temp - *(tmp + 1)): (*(tmp + 1)
                      - temp);
            tmp += 2;
         }
         jd[i] /= NUM;
         avr_jd += jd[i];
      }
      avr_jd /= NN;
      avr_jd *= 0.2;
      for (i = 1; i < NN; i++)
         if (jd[i] >= avr_jd)
            for (j = 0; j < N; j++)
               gene[i][j] = gene[i - 1][j] + (double)(rand() % 30) - 15;
      if (!(ttt % 1))
         printf("计算精度=%lf\n", avr_jd *10);
   }
   j = 0;
   for (i = 0; i < NN; i++)
      if (jd[j] > jd[i])
         j = i;
   printf("结果: ");
   for (i = 0; i < N; i++)
      printf(" %lf", gene[j][i]);
   printf("\n");
}
int main(int argc, char *argv[])
{
   FILE *fp;
   int n;
   int num;
   double *x;
   if (!(fp = fopen("r.dat", "rb")))
      die("Error 1: 文件打开失败");
   if (fread(&n, sizeof(int), 1, fp) != 1)
      die("Error 2: 读取n");
   if (fread(&num, sizeof(int), 1, fp) != 1)
      die("Error 3: 读取num");
   x = (double*)malloc(2 *num * sizeof(double));
   if (!x)
      die("Error 4: 分配内存失败");
   if (fread(x, sizeof(double), num *2, fp) != 2 *num)
      die("Error 5: 读取验证数据");
   if (!calc(n, num, x))
      die("Error 0: ");
   return 0;
}
